deno bundleの代替コード
実装
2024-02-14
12:34:15 依存関係表示プログラムはinfo.tsに移した
12:31:36 deno-cliffyのansiを使って、infoを再描画できるようにしてみようとしたのだが、うまく消えなかったので断念した code:build.ts
import {
denoResolverPlugin,
denoLoaderPlugin
const result = await build({
entryPoints: [Deno.args0], bundle: true,
write: false,
format: "esm",
minify: true,
charset: "utf8",
});
console.log(result.outputFiles0.text); stop();
denoResolverPlugin()を通した後は、OnResolveArgs .importerが消えてしまう
denoResolverPlugin()の前にいれると、依存関係が保存された処理前のOnLoadArgsと、処理後のOnLoadArgsの両方を取得できる
code:info.ts
import {
denoResolverPlugin,
denoLoaderPlugin
/** keyが親ファイルパス, valueがそのファイルでimportしたファイルのパスリスト */
const ancestors = new Map<string, string[]>;
let entryPoint = "";
function* makeTree(
parent: string,
// parentからの相対URLで表示したいときtrue
relative?: boolean,
viewedPath?: Set<string>,
): Generator<string> {
const childs = ancestors.get(parent);
if (!childs) return;
viewedPath ??= new Set<string>();
viewedPath.add(parent);
for (let i = 0; i < childs.length; i++) {
const relativePath = decodeURIComponent(
relative ? makeRelative(new URL(parent), new URL(child)) : child,
);
const lastOne = i + 1 === childs.length;
const branch = lastOne ? "└─ " : "├─ ";
// 一度読み込んだものは灰色で表示する
if (viewedPath.has(child)) {
yield ${branch}${gray(relativePath)};
continue;
}
yield ${branch}${relativePath};
viewedPath.add(child);
const indent = lastOne ? " " : "│ ";
for (const line of makeTree(child, relative ?? false, viewedPath)) {
yield ${indent}${line};
}
}
}
const listPlugin: Plugin = {
name: "list-imports",
setup: ({ onResolve, resolve }) => {
onResolve({ filter: /.*/, }, (args) => {
/**
* Copyright (c) 2021 Luca Casonato. All rights reserved. MIT license.
*/
//
// The first pass resolver performs synchronous resolution. This
// includes relative to absolute specifier resolution and import map
// resolution.
// We have to first determine the referrer URL to use when resolving
// the specifier. This is either the importer URL, or the resolveDir
// URL if the importer is not specified (ie if the specifier is at the
// root).
let referrer: URL;
if (args.importer !== "") {
if (args.namespace === "") {
throw new Error("assert namespace is empty"); }
referrer = new URL(${args.namespace}:${args.importer});
} else if (args.resolveDir !== "") {
referrer = new URL(${toFileUrl(args.resolveDir).href}/);
} else {
return undefined;
}
// We can then resolve the specifier relative to the referrer URL. If
// an import map is specified, we use that to resolve the specifier.
const resolved = new URL(args.path, referrer);
if (args.kind === "entry-point") {
entryPoint = resolved.href;
} else {
ancestors.set(
referrer.href,
[...(ancestors.get(referrer.href) ?? []), resolved.href]
);
}
return undefined;
});
},
};
await build({
entryPoints: [Deno.args0], bundle: true,
write: false,
format: "esm",
minify: true,
charset: "utf8",
});
stop();
console.log(entryPoint);
for (const line of makeTree(entryPoint)) {
console.log(line);
}
長すぎるコードを読み込むときに使う
code:json.ts
import {
denoResolverPlugin,
denoLoaderPlugin
const result = await esbuild.build({
entryPoints: [Deno.args0], bundle: true,
write: false,
format: "esm",
minify: true,
charset: "utf8",
});
const pages = [{
lines: [
"",
"code:mod.js",
...result.outputFiles0.text.split("\n").map((line) => ${line}), ],
}];
console.log(JSON.stringify({pages}));
stop();